-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local Databases = require 'database'
local Col = require 'database.column'

local Chassis = require 'chassis.json_types.Chassis'
local Properties = require 'chassis.json_types.Properties'

---@class LedPolicyTable: Table
---@field Normal FieldBase
---@field Minor FieldBase
---@field Major FieldBase
---@field Critical FieldBase
---@field ClassName FieldBase
---@field ObjectName FieldBase
---@field ObjectIdentifier FieldBase
---@field Id FieldBase

---@class LedTable: Table
---@field SystemId FieldBase
---@field Name FieldBase
---@field OnDuration FieldBase
---@field OffDuration FieldBase
---@field Capability FieldBase
---@field State FieldBase
---@field Id FieldBase
---@field FruId FieldBase
---@field ColorCapabilities FieldBase
---@field LocalControlStateColor FieldBase
---@field OverrideStateColor FieldBase
---@field Mode FieldBase
---@field ClassName FieldBase
---@field ObjectName FieldBase
---@field ObjectIdentifier FieldBase
---@field CtrlValue FieldBase
---@field DefaultOSColor FieldBase
---@field DefaultLCSColor FieldBase
---@field LCSColor FieldBase
---@field LCSState FieldBase
---@field OSColor FieldBase
---@field OSState FieldBase
---@field LampTestColor FieldBase
---@field LampTestDuration FieldBase

---@class ChassisTable: Table
---@field Name FieldBase
---@field IntrusionFlag FieldBase
---@field UidButtonPressed FieldBase
---@field UidButtonLongPressed FieldBase
---@field ChassisType FieldBase
---@field Location FieldBase
---@field TopologyConfigId FieldBase
---@field DeviceSpecication FieldBase
---@field ClassName FieldBase
---@field ObjectName FieldBase
---@field ObjectIdentifier FieldBase
---@field IntrusionACOn FieldBase
---@field IntrusionACOff FieldBase
---@field IntrusionACOnClear FieldBase
---@field IntrusionACOffClear FieldBase
---@field CoverStatus FieldBase
---@field LastIntrusionACOn FieldBase
---@field UidButtonAccessor FieldBase
---@field UidButtonScanner FieldBase
---@field UidButtonLongAccessor FieldBase
---@field UidButtonLongScanner FieldBase
---@field UidButtonTestFlag FieldBase
---@field UidButtonTestResult FieldBase
---@field UidButtonTestStatus FieldBase

---@class ChassisTableTable: Table
---@field Id FieldBase
---@field BmcHardResetFlag FieldBase
---@field ProcessRestartFlag FieldBase

---@class SuperPodLabelTable: Table
---@field SuperPodId FieldBase
---@field ServerIndex FieldBase
---@field SuperPodSize FieldBase
---@field SuperPodEnabled FieldBase
---@field ClassName FieldBase
---@field ObjectName FieldBase
---@field ObjectIdentifier FieldBase
---@field Id FieldBase
---@field SuperPodIdAcc FieldBase
---@field ServerIndexAcc FieldBase
---@field SuperPodSizeAcc FieldBase
---@field DefaultSuperPodId FieldBase
---@field DefaultServerIndex FieldBase
---@field DefaultSuperPodSize FieldBase
---@field Crc16 FieldBase

---@class ChassisDBDatabase
---@field db DataBase
---@field select fun(db:DataBase, table: any, ...): SelectStatement
---@field update fun(db:DataBase, table: any, ...): UpdateStatement
---@field insert fun(db:DataBase, table: any, ...): InsertStatement
---@field LedPolicy LedPolicyTable
---@field Led LedTable
---@field Chassis ChassisTable
---@field ChassisTable ChassisTableTable
---@field SuperPodLabel SuperPodLabelTable
local ChassisDBDatabase = {}
ChassisDBDatabase.__index = ChassisDBDatabase

function ChassisDBDatabase.new(path, datas)
    local db = Databases(path)
    local obj = {db = db}

    obj.LedPolicy = db:Table('t_LedPolicy', {
        Normal = Col.JsonField():cid(1):persistence_key('protect_power_off'):null(),
        Minor = Col.JsonField():cid(2):persistence_key('protect_power_off'):null(),
        Major = Col.JsonField():cid(3):persistence_key('protect_power_off'):null(),
        Critical = Col.JsonField():cid(4):persistence_key('protect_power_off'):null(),
        ClassName = Col.TextField():cid(5):null(),
        ObjectName = Col.TextField():cid(6):null(),
        ObjectIdentifier = Col.JsonField():cid(7):null(),
        Id = Col.IntegerField():cid(8):primary_key():max_length(8):default(1)
    }):create_if_not_exist(datas and datas['t_LedPolicy'])
    obj.Led = db:Table('t_Led', {
        SystemId = Col.IntegerField():cid(1):null():max_length(8),
        Name = Col.TextField():cid(2):null(),
        OnDuration = Col.IntegerField():cid(3):null():max_length(8):default(0),
        OffDuration = Col.IntegerField():cid(4):null():max_length(8):default(0),
        Capability = Col.IntegerField():cid(5):null():max_length(8),
        State = Col.IntegerField():cid(6):persistence_key('protect_reset'):null():max_length(8),
        Id = Col.IntegerField():cid(7):primary_key():max_length(8),
        FruId = Col.IntegerField():cid(8):null():max_length(8),
        ColorCapabilities = Col.IntegerField():cid(9):null():max_length(8),
        LocalControlStateColor = Col.TextField():cid(10):null(),
        OverrideStateColor = Col.TextField():cid(11):null(),
        Mode = Col.IntegerField():cid(12):null():max_length(8),
        ClassName = Col.TextField():cid(13):null(),
        ObjectName = Col.TextField():cid(14):null(),
        ObjectIdentifier = Col.JsonField():cid(15):null(),
        CtrlValue = Col.IntegerField():cid(16):null():max_length(8),
        DefaultOSColor = Col.IntegerField():cid(17):null():max_length(8),
        DefaultLCSColor = Col.IntegerField():cid(18):null():max_length(8),
        LCSColor = Col.IntegerField():cid(19):null():max_length(8),
        LCSState = Col.IntegerField():cid(20):null():max_length(8),
        OSColor = Col.IntegerField():cid(21):null():max_length(8),
        OSState = Col.IntegerField():cid(22):null():max_length(8),
        LampTestColor = Col.IntegerField():cid(23):null():max_length(8),
        LampTestDuration = Col.IntegerField():cid(24):null():max_length(8)
    }):create_if_not_exist(datas and datas['t_Led'])
    obj.Chassis = db:Table('t_Chassis', {
        Name = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        IntrusionFlag = Col.IntegerField():cid(2):null():max_length(8),
        UidButtonPressed = Col.IntegerField():cid(3):null():max_length(8),
        UidButtonLongPressed = Col.IntegerField():cid(4):null():max_length(8),
        ChassisType = Col.IntegerField():cid(5):null():max_length(8),
        Location = Col.TextField():cid(6):persistence_key('protect_power_off'):null(),
        TopologyConfigId = Col.IntegerField():cid(7):null():max_length(16):default(65535),
        DeviceSpecication = Col.JsonField():cid(8):null(),
        ClassName = Col.TextField():cid(9):null(),
        ObjectName = Col.TextField():cid(10):null(),
        ObjectIdentifier = Col.JsonField():cid(11):null(),
        IntrusionACOn = Col.IntegerField():cid(12):null():max_length(8),
        IntrusionACOff = Col.IntegerField():cid(13):null():max_length(8),
        IntrusionACOnClear = Col.IntegerField():cid(14):null():max_length(8),
        IntrusionACOffClear = Col.IntegerField():cid(15):null():max_length(8),
        CoverStatus = Col.IntegerField():cid(16):null():max_length(8),
        LastIntrusionACOn = Col.IntegerField():cid(17):persistence_key('protect_power_off'):null():max_length(8)
            :default(0),
        UidButtonAccessor = Col.IntegerField():cid(18):null():max_length(8),
        UidButtonScanner = Col.IntegerField():cid(19):null():max_length(8),
        UidButtonLongAccessor = Col.IntegerField():cid(20):null():max_length(8),
        UidButtonLongScanner = Col.IntegerField():cid(21):null():max_length(8),
        UidButtonTestFlag = Col.BooleandField():cid(22):null():default(true),
        UidButtonTestResult = Col.IntegerField():cid(23):null():max_length(8):default(255),
        UidButtonTestStatus = Col.IntegerField():cid(24):null():max_length(8):default(129)
    }):create_if_not_exist(datas and datas['t_Chassis'])
    obj.ChassisTable = db:Table('t_chassis_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_reset'),
        BmcHardResetFlag = Col.IntegerField():cid(2):persistence_key('protect_reset'):null():max_length(8):default(0),
        ProcessRestartFlag = Col.IntegerField():cid(3):persistence_key('protect_temporary'):null():max_length(8)
            :default(0)
    }):create_if_not_exist(datas and datas['t_chassis_info'])
    obj.SuperPodLabel = db:Table('t_SuperPodLabel', {
        SuperPodId = Col.IntegerField():cid(1):persistence_key('protect_power_off'):null():max_length(32):default(
            4294967295),
        ServerIndex = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(16)
            :default(65535),
        SuperPodSize = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(16):default(384),
        SuperPodEnabled = Col.BooleandField():cid(4):persistence_key('protect_power_off'):null():default(false),
        ClassName = Col.TextField():cid(5):null(),
        ObjectName = Col.TextField():cid(6):null(),
        ObjectIdentifier = Col.JsonField():cid(7):null(),
        Id = Col.IntegerField():cid(8):primary_key():max_length(8):default(1),
        SuperPodIdAcc = Col.IntegerField():cid(9):null():max_length(32),
        ServerIndexAcc = Col.IntegerField():cid(10):null():max_length(16),
        SuperPodSizeAcc = Col.IntegerField():cid(11):null():max_length(16),
        DefaultSuperPodId = Col.IntegerField():cid(12):null():max_length(32):default(4294967295),
        DefaultServerIndex = Col.IntegerField():cid(13):null():max_length(16):default(65535),
        DefaultSuperPodSize = Col.IntegerField():cid(14):null():max_length(16):default(384),
        Crc16 = Col.IntegerField():cid(15):null():max_length(16):default(0)
    }):create_if_not_exist(datas and datas['t_SuperPodLabel'])

    obj.tables = db.tables
    return setmetatable(obj, ChassisDBDatabase)
end

function ChassisDBDatabase:select(table, ...)
    return self.db:select(table, ...)
end

function ChassisDBDatabase:update(table, ...)
    return self.db:update(table, ...)
end

function ChassisDBDatabase:insert(table, ...)
    return self.db:insert(table, ...)
end

function ChassisDBDatabase:delete(table, ...)
    return self.db:delete(table, ...)
end

function ChassisDBDatabase:exec(...)
    return self.db:exec(...)
end

return ChassisDBDatabase.new
